package com.demo.zhlg.config;

import com.demo.zhlg.util.JwtFilter;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;

import java.io.IOException;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtFilter jwtFilter;
    @Autowired
    private HandlerExceptionResolver handlerExceptionResolver;

    @Bean
    AuthenticationManager authenticationManager() throws Exception{
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
        return new ProviderManager(daoAuthenticationProvider);
    }
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.formLogin(AbstractHttpConfigurer::disable);
        http.httpBasic(AbstractHttpConfigurer::disable);
        http.csrf(AbstractHttpConfigurer::disable);
        http.cors(Customizer.withDefaults());
        http.authorizeHttpRequests(
                req-> req.requestMatchers("/users/login/**").permitAll()
                        .requestMatchers("/users/register/**").permitAll()
                        .requestMatchers("/users/forgotPassword").permitAll()
                        .requestMatchers("/tasks/getTaskList").permitAll()
                        .requestMatchers("/tasks/getTaskDetail/**").permitAll()
                        .requestMatchers("/tasks/getSimilarTasks/**").permitAll()
                        .requestMatchers("/tasks/searchTasks/**").permitAll()
                        .requestMatchers("/tasks/getTaskByCategory").permitAll()
                        .requestMatchers("/users/getAvatarById").permitAll()
                        .requestMatchers("/tasks/updateTaskExpiration").permitAll()
                        .requestMatchers("/users/uploadAvatar").permitAll()
                        .requestMatchers("/").permitAll()
                        .anyRequest().authenticated()
                        //.anyRequest().permitAll()
        );
        http.exceptionHandling(exp->exp.authenticationEntryPoint(new AuthenticationEntryPoint() {
            @Override
            public void commence(
                    HttpServletRequest request,
                    HttpServletResponse response,
                    AuthenticationException authException) throws IOException, ServletException {
                handlerExceptionResolver.resolveException(request,response, null, authException);
            }
        }));
        http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
}